package com.happy.system.repository.impl;

import com.happy.system.domain.*;
import com.happy.system.domain.dto.EmotionDataGroupDto;
import com.happy.system.domain.vo.EmotionDataInfo;
import com.happy.system.domain.vo.NumberInfo;
import com.happy.system.mapper.SysDeptMapper;
import com.happy.system.repository.ReportRepository;
import com.happy.system.service.IEmployeeService;
import com.happy.system.service.impl.EmployeeServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;


@Repository
public class ReportRepositoryImpl implements ReportRepository {
    private static final String EMPLOYEEID = "employee_id";
    private static final String DEPTID = "dept_id";
    private static final String STRESS = "stress";
    private static final String CREATETIME = "create_time";
    private static final String EMOTION = "emotion";

    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    IEmployeeService employeeService;
    @Autowired
    SysDeptMapper deptMapper;

    /**
     * 获得员工历史主情绪
     * @param employee_id
     * @return
     */
   @Override
    public List<EmoList> getEmoList(Long employee_id){

        List<EmoList> emoLists=new ArrayList<>();

        // 查询数据库获取指定员工的报告列表
        Query query = new Query(Criteria.where(EMPLOYEEID).is(employee_id));
        List<Report> reports = mongoTemplate.find(query, Report.class);

        //拿到情绪最大值，生成情绪记录
        for (Report report : reports) {
            double happy = report.getHappy();
            double sad = report.getSad();
            double surprised = report.getSurprised();
            double anger = report.getAnger();
            double neutral = report.getNeutral();
            double fear = report.getFear();
            double disgust = report.getDisgust();

            double maxEmotion = Math.max(Math.max(happy, sad), Math.max(Math.max(surprised, anger), Math.max(Math.max(neutral, fear), disgust)));
            String emotion = "";

            if (maxEmotion == happy) {
                emotion = "高兴";
            } else if (maxEmotion == sad) {
                emotion = "伤心";
            } else if (maxEmotion == surprised) {
                emotion = "惊讶";
            } else if (maxEmotion == anger) {
                emotion = "生气";
            } else if (maxEmotion == neutral) {
                emotion = "自然";
            } else if (maxEmotion == fear) {
                emotion = "害怕";
            } else if (maxEmotion == disgust) {
                emotion = "厌恶";
            }

            // 将创建时间转换为 "yyyy-MM-dd" 格式的字符串
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String createTimeStr = sdf.format(report.getCreate_time());

            EmoList emotionList = new EmoList(emotion, createTimeStr);
            emoLists.add(emotionList);
        }
        return emoLists;
    }

    /**
     * 获得各部门当日检测人数
     * @return
     */
    @Override
    public List<ReportDept> getReportCountByDepartment(){


        // 获取当前日期
        Date today = new Date();

        // 构建查询条件
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(today);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date startOfDay = calendar.getTime();

        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        Date endOfDay = calendar.getTime();

        // 创建查询对象
        Query query = new Query();
        query.addCriteria(Criteria.where("create_time").gte(startOfDay).lte(endOfDay));

        // 执行查询得到当日所有报告
        List<Report> reports = mongoTemplate.find(query, Report.class);

        // 统计每个部门的报告数量
        Map<String, Integer> deptCounts = new HashMap<>();
        for (Report report : reports) {
            String deptName = report.getDept_name();
            deptCounts.put(deptName, deptCounts.getOrDefault(deptName, 0) + 1);
        }
        // 将结果转换为List<ReportDept>
        List<ReportDept> result = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : deptCounts.entrySet()) {
            ReportDept reportDept = new ReportDept();
            reportDept.setDeptName(entry.getKey());
            reportDept.setNum(entry.getValue());
            result.add(reportDept);
        }
        /*for (ReportDept report : result) {
            System.out.println(report.getDeptName()+report.getNum());
        }*/
        return result;
    }

    /**
     * 获得各部门当日高压人数
     * @return
     */
    @Override
    public List<StressDept> getStressCountByDepartment(){
        // 获取当前日期
        Date today = new Date();

        // 构建查询条件
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(today);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date startOfDay = calendar.getTime();

        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        Date endOfDay = calendar.getTime();

        // 创建查询对象
        Query query = new Query();
        query.addCriteria(Criteria.where("create_time").gte(startOfDay).lte(endOfDay));
        query.addCriteria(Criteria.where("stress").gt(70));

        // 执行查询得到当日所有高压力员工
        List<Report> highStressReports = mongoTemplate.find(query, Report.class);

        // 统计每个部门的高压力人数
        Map<String, Integer> highStressDeptCounts = new HashMap<>();
        for (Report report : highStressReports) {
            String deptName = report.getDept_name();
            highStressDeptCounts.put(deptName, highStressDeptCounts.getOrDefault(deptName, 0) + 1);
        }

        // 将结果转换为List<ReportDept>
        List<StressDept> result = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : highStressDeptCounts.entrySet()) {
            StressDept reportDept = new StressDept();
            reportDept.setDeptName(entry.getKey());
            reportDept.setNum(entry.getValue());
            result.add(reportDept);
        }
        //测试
        /*for (StressDept report : result) {
            System.out.println(report.getDeptName()+report.getNum());
        }*/
        return result;
    }

    @Override
    public NumberInfo getHighStressNumInfoOfDept(Long dept_id) {
        NumberInfo numberInfo = new NumberInfo();
        Date today = new Date();
        today.setHours(0);
        today.setMinutes(0);
        today.setSeconds(0);
        Query query = new Query(Criteria.where(DEPTID).is(dept_id).
                and(STRESS).gte(71).
                and(CREATETIME).gte(today));
        List<Report> reports = mongoTemplate.find(query,Report.class);
        int male = 0;
        int female = 0;
        for(Report report : reports){
            String sex = employeeService.queryEmployeeById(report.getEmployee_id()).getSex();
            if(sex.equals("0"))
                ++male;
            else
                ++female;
        }
        numberInfo.setSum(reports.size());
        numberInfo.setMale(male);
        numberInfo.setFemale(female);
        return numberInfo;
    }

    @Override
    public NumberInfo getMidStressNumInfoOfDept(Long dept_id) {
        NumberInfo numberInfo = new NumberInfo();
        Date today = new Date();
        today.setHours(0);
        today.setMinutes(0);
        today.setSeconds(0);
        Query query = new Query(Criteria.where(DEPTID).is(dept_id).
                and(STRESS).gte(41).lte(70).
                and(CREATETIME).gte(today));
        List<Report> reports = mongoTemplate.find(query,Report.class);
        int male = 0;
        int female = 0;
        for(Report report : reports){
            String sex = employeeService.queryEmployeeById(report.getEmployee_id()).getSex();
            if(sex.equals("0"))
                ++male;
            else
                ++female;
        }
        numberInfo.setSum(reports.size());
        numberInfo.setMale(male);
        numberInfo.setFemale(female);
        return numberInfo;
    }

    @Override
    public NumberInfo getlowStressNumInfoOfDept(Long dept_id) {
        NumberInfo numberInfo = new NumberInfo();
        Date today = new Date();
        today.setHours(0);
        today.setMinutes(0);
        today.setSeconds(0);
        Query query = new Query(Criteria.where(DEPTID).is(dept_id).
                and(STRESS).lte(40).
                and(CREATETIME).gte(today));
        List<Report> reports = mongoTemplate.find(query,Report.class);
        int male = 0;
        int female = 0;
        for(Report report : reports){
            String sex = employeeService.queryEmployeeById(report.getEmployee_id()).getSex();
            if(sex.equals("0"))
                ++male;
            else
                ++female;
        }
        numberInfo.setSum(reports.size());
        numberInfo.setMale(male);
        numberInfo.setFemale(female);
        return numberInfo;
    }

    @Override
    public List<Employee> getHighestStressEmployeeOfDept(Long dept_id) {
        List<Employee> employees = new ArrayList<>();
        Date today = new Date();
        today.setHours(0);
        today.setMinutes(0);
        today.setSeconds(0);
        Query query = new Query(Criteria.where(DEPTID).is(dept_id).
                and(CREATETIME).gte(today)).
                with(Sort.by(STRESS)).limit(3);
        List<Report> reports = mongoTemplate.find(query,Report.class);
        for(Report report:reports){
            Employee employee = employeeService.queryEmployeeById(report.getEmployee_id());
            employees.add(employee);
        }
        return employees;
    }

    @Override
    public  List<Report> getReportToday(Long deptId) {
        Date today = new Date();
        today.setHours(0);
        today.setMinutes(0);
        today.setSeconds(0);
        // 构建查询条件
        Criteria criteria = Criteria.where(CREATETIME).gte(today);
        if (deptId != null) {
            criteria = criteria.and(DEPTID).is(deptId);
        }

        Query query = new Query(criteria);
        List<Report> list=mongoTemplate.find(query, Report.class);
        return list;
    }

    public List<Report> findAll() {
        List<Report>list=mongoTemplate.findAll(Report.class);
        return list;
    }

    public Map<Long,List<Integer>>getTableDataInfo(){
        Date today=new Date();
        today.setHours(0);
        today.setMinutes(0);
        today.setSeconds(0);

        Aggregation aggregation = Aggregation.newAggregation(
                // 匹配符合条件的记录，例如创建时间大于等于今天
                Aggregation.match(Criteria.where(CREATETIME).gte(today)),

                // 分组操作，按照部门ID和情绪字段进行分组，并计算每种情绪的数量
                Aggregation.group(DEPTID, EMOTION)
                        .first(DEPTID).as(DEPTID)
                        .first(EMOTION).as(EMOTION)
                        .count().as("sum")

//                // 可选的排序操作，按照需要排序
//                Aggregation.sort(Sort.by(Sort.Order.asc("_id.DEPTID")))
        );

        AggregationResults<EmotionDataGroupDto> aggregationResults = mongoTemplate.aggregate(
                aggregation, "Report", EmotionDataGroupDto.class
        );

        List<EmotionDataGroupDto> Reports = aggregationResults.getMappedResults();

        Map<Long, List<EmotionDataGroupDto>> map = Reports.stream()
                .collect(Collectors.groupingBy(EmotionDataGroupDto::getDept_id));

        Map<Long,List<Integer>> data=new HashMap<>();

        map.forEach((key, value) -> {
            List<EmotionDataGroupDto> emotionDataGroupList = value;

            //初始化每种情绪的数量为0，假设有7种情绪
            List<Integer> emotionCounts = new ArrayList<>(Collections.nCopies(7, 0));

            for (EmotionDataGroupDto emotionDataGroup : emotionDataGroupList) {
                String emotion = emotionDataGroup.getEmotion();
                int index = getEmotionIndex(emotion); // 获取情绪的索引
                emotionCounts.set(index, emotionCounts.get(index) + emotionDataGroup.getSum());
            }

            data.put(key, emotionCounts);

            // 查找当前部门的所有上级部门
            List<Long> ancestors = convertStringToList(deptMapper.getDeptAncestorById(key)); // 假设有一个方法来获取上级部门ID列表
            for (Long ancestor : ancestors) {
                if(ancestor!=0L){
                    data.merge(ancestor, new ArrayList<>(emotionCounts), (oldValue, newValue) -> {
                        for (int i = 0; i < oldValue.size(); i++) {
                            oldValue.set(i, oldValue.get(i) + newValue.get(i));
                        }
                        return oldValue;
                    });
                }
            }
        });
        return data;
    }

    // 获取情绪的索引，假设有7种情绪："happy", "sad", "angry", "neutral", "surprised", "disgusted", "fearful"
    private static int getEmotionIndex(String emotion) {
        switch (emotion) {
            case "happy": return 0;
            case "sad": return 1;
            case "angry": return 2;
            case "neutral": return 3;
            case "surprised": return 4;
            case "disgust": return 5;
            case "fear": return 6;
            default: throw new IllegalArgumentException("Unknown emotion: " + emotion);
        }
    }


    public List<Long> convertStringToList(String ancestors) {
        if (ancestors!= null) {
            // 将逗号分隔的字符串转换为 List<Long>
            return Arrays.stream(ancestors.split(","))
                    .map(Long::valueOf)
                    .collect(Collectors.toList());
        } else {
            return Collections.emptyList(); //处理空情况
        }
    }
}
